package com.xiaozhi.exception;

import com.xiaozhi.dto.ErrorResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.validation.FieldError;

import java.util.concurrent.TimeoutException;
import java.util.stream.Collectors;
import java.net.SocketTimeoutException;
import java.net.ConnectException;
import java.io.IOException;

/**
 * 全局异常处理器
 * 统一处理应用中的各种异常，特别是AI服务相关的异常
 */
@ControllerAdvice
public class GlobalExceptionHandler {
    
    private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
    
    /**
     * 处理API密钥相关异常
     */
    @ExceptionHandler({IllegalArgumentException.class})
    public ResponseEntity<ErrorResponse> handleApiKeyException(IllegalArgumentException e, WebRequest request) {
        log.error("API密钥配置错误: {}", e.getMessage());
        
        ErrorResponse errorResponse = new ErrorResponse(
            "API_KEY_ERROR",
            "API密钥配置错误，请联系管理员",
            e.getMessage(),
            request.getDescription(false).replace("uri=", "")
        );
        
        return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(errorResponse);
    }
    
    /**
     * 处理超时异常
     */
    @ExceptionHandler({TimeoutException.class, SocketTimeoutException.class})
    public ResponseEntity<ErrorResponse> handleTimeoutException(Exception e, WebRequest request) {
        log.error("请求超时: {}", e.getMessage());
        
        ErrorResponse errorResponse = new ErrorResponse(
            "TIMEOUT_ERROR",
            "请求超时，请稍后重试",
            "AI服务响应时间过长，请检查网络连接或稍后重试",
            request.getDescription(false).replace("uri=", "")
        );
        
        return ResponseEntity.status(HttpStatus.REQUEST_TIMEOUT).body(errorResponse);
    }
    
    /**
     * 处理网络连接异常
     */
    @ExceptionHandler({ConnectException.class, IOException.class})
    public ResponseEntity<ErrorResponse> handleNetworkException(Exception e, WebRequest request) {
        log.error("网络连接异常: {}", e.getMessage());
        
        ErrorResponse errorResponse = new ErrorResponse(
            "NETWORK_ERROR",
            "网络连接失败，请检查网络设置",
            e.getMessage(),
            request.getDescription(false).replace("uri=", "")
        );
        
        return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).body(errorResponse);
    }
    
    /**
     * 处理重试失败异常
     */
    @ExceptionHandler(RetryFailedException.class)
    public ResponseEntity<ErrorResponse> handleRetryFailedException(RetryFailedException e, WebRequest request) {
        log.error("重试操作失败: {} (操作: {}, 重试次数: {})", e.getMessage(), e.getOperationName(), e.getMaxRetries());
        
        String errorType = e.getErrorType();
        String userMessage = e.getUserFriendlyMessage();
        HttpStatus httpStatus;
        
        // 根据错误类型设置HTTP状态码
        switch (errorType) {
            case "NETWORK_ERROR":
                httpStatus = HttpStatus.SERVICE_UNAVAILABLE;
                break;
            case "SERVER_ERROR":
                httpStatus = HttpStatus.BAD_GATEWAY;
                break;
            case "RATE_LIMIT_ERROR":
                httpStatus = HttpStatus.TOO_MANY_REQUESTS;
                break;
            case "AUTH_ERROR":
                httpStatus = HttpStatus.UNAUTHORIZED;
                break;
            default:
                httpStatus = HttpStatus.INTERNAL_SERVER_ERROR;
        }
        
        ErrorResponse errorResponse = new ErrorResponse(
            errorType,
            userMessage,
            String.format("操作 '%s' 在 %d 次重试后失败: %s", 
                e.getOperationName(), e.getMaxRetries(), 
                e.getLastException() != null ? e.getLastException().getMessage() : "未知错误"),
            request.getDescription(false).replace("uri=", "")
        );
        
        return ResponseEntity.status(httpStatus).body(errorResponse);
    }
    
    /**
     * 处理频率限制异常
     */
    @ExceptionHandler(RuntimeException.class)
    public ResponseEntity<ErrorResponse> handleRateLimitException(RuntimeException e, WebRequest request) {
        String message = e.getMessage();
        
        // 检查是否为频率限制错误
        if (message != null && (message.contains("rate limit") || message.contains("429") || message.contains("Too Many Requests"))) {
            log.warn("API频率限制: {}", message);
            
            ErrorResponse errorResponse = new ErrorResponse(
                "RATE_LIMIT_ERROR",
                "请求过于频繁，请稍后重试",
                "已达到API调用频率限制，请等待一段时间后重试",
                request.getDescription(false).replace("uri=", "")
            );
            
            return ResponseEntity.status(HttpStatus.TOO_MANY_REQUESTS).body(errorResponse);
        }
        
        // 检查是否为认证错误
        if (message != null && (message.contains("401") || message.contains("Unauthorized") || message.contains("authentication"))) {
            log.error("认证失败: {}", message);
            
            ErrorResponse errorResponse = new ErrorResponse(
                "AUTH_ERROR",
                "认证失败，请检查API密钥配置",
                message,
                request.getDescription(false).replace("uri=", "")
            );
            
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(errorResponse);
        }
        
        // 其他运行时异常
        log.error("运行时异常: {}", message, e);
        
        ErrorResponse errorResponse = new ErrorResponse(
            "RUNTIME_ERROR",
            "服务暂时不可用，请稍后重试",
            message,
            request.getDescription(false).replace("uri=", "")
        );
        
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResponse);
    }
    
    /**
     * 处理参数验证异常
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<ErrorResponse> handleValidationException(MethodArgumentNotValidException e, WebRequest request) {
        log.warn("参数验证失败: {}", e.getMessage());
        
        String details = e.getBindingResult().getFieldErrors().stream()
            .map(FieldError::getDefaultMessage)
            .collect(Collectors.joining(", "));
        
        ErrorResponse errorResponse = new ErrorResponse(
            "VALIDATION_ERROR",
            "请求参数验证失败",
            details,
            request.getDescription(false).replace("uri=", "")
        );
        
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorResponse);
    }
    
    /**
     * 处理非法状态异常（如环境变量未配置）
     */
    @ExceptionHandler(IllegalStateException.class)
    public ResponseEntity<ErrorResponse> handleIllegalStateException(IllegalStateException e, WebRequest request) {
        log.error("系统配置错误: {}", e.getMessage());
        
        ErrorResponse errorResponse = new ErrorResponse(
            "CONFIG_ERROR",
            "系统配置错误，请联系管理员",
            e.getMessage(),
            request.getDescription(false).replace("uri=", "")
        );
        
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResponse);
    }
    
    /**
     * 处理其他未捕获的异常
     */
    @ExceptionHandler(Exception.class)
    public ResponseEntity<ErrorResponse> handleGenericException(Exception e, WebRequest request) {
        log.error("未处理的异常: {}", e.getMessage(), e);
        
        ErrorResponse errorResponse = new ErrorResponse(
            "INTERNAL_ERROR",
            "系统内部错误，请稍后重试",
            "系统遇到未知错误，请联系技术支持",
            request.getDescription(false).replace("uri=", "")
        );
        
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorResponse);
    }
}